using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Views.Grid;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using twistmachinev2.Entity;
using twistmachinev2.OPCUA;
using twistmachinev2.Repository;

namespace twistmachinev2.Business
{
    /// <summary>
    /// Excel导入窗体
    /// </summary>
    public partial class FrmExcelImport : XtraForm
    {
        private OpcUaConfigService _configService;
        private OPCUARepository _repository;
        private DataTable _importDataTable;
        private List<OpcUaNodeConfigEntity> _previewNodes;
        private Dictionary<OpcUaNodeConfigEntity, Dictionary<string, object>> _nodeProperties;
        private bool _isDataLoaded = false;

        public FrmExcelImport()
        {
            InitializeComponent();
            InitializeServices();
            InitializeUI();
        }

     

        /// <summary>
        /// 初始化服务
        /// </summary>
        private void InitializeServices()
        {
            try
            {
                _repository = new OPCUARepository();
                _configService = new OpcUaConfigService(_repository);
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show($"初始化服务失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 初始化UI
        /// </summary>
        private void InitializeUI()
        {
            // 设置窗体属性
            this.Text = "Excel数据导入";
            this.WindowState = FormWindowState.Maximized;
            this.StartPosition = FormStartPosition.CenterScreen;

            // 初始化数据表
            _importDataTable = new DataTable();
            _previewNodes = new List<OpcUaNodeConfigEntity>();
            _nodeProperties = new Dictionary<OpcUaNodeConfigEntity, Dictionary<string, object>>();

            // 绑定事件
            BindEvents();

            // 设置初始状态
            UpdateUIState();
        }

        /// <summary>
        /// 绑定事件
        /// </summary>
        private void BindEvents()
        {
            // 工具栏事件
            btnSelectFile.Click += BtnSelectFile_Click;
            btnPreview.Click += BtnPreview_Click;
            btnImport.Click += BtnImport_Click;
            btnClear.Click += BtnClear_Click;
            btnClose.Click += BtnClose_Click;

            // 网格事件
            gridViewPreview.CustomDrawRowIndicator += GridViewPreview_CustomDrawRowIndicator;
            
            // 添加右键菜单
            var contextMenu = new ContextMenuStrip();
            contextMenu.Items.Add("生成导入模板", null, GenerateTemplate_Click);
            contextMenu.Items.Add("导出当前数据", null, ExportData_Click);
            btnSelectFile.ContextMenuStrip = contextMenu;
        }

        #region 事件处理

        /// <summary>
        /// 选择文件按钮点击事件
        /// </summary>
        private void BtnSelectFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog()
            {
                Filter = "Excel文件|*.xlsx;*.xls",
                Title = "选择Excel文件",
                Multiselect = false
            };

            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    txtFilePath.Text = openFileDialog.FileName;
                    LoadExcelData(openFileDialog.FileName);
                }
                catch (Exception ex)
                {
                    XtraMessageBox.Show($"读取Excel文件失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        /// <summary>
        /// 预览按钮点击事件
        /// </summary>
        private void BtnPreview_Click(object sender, EventArgs e)
        {
            if (!_isDataLoaded)
            {
                XtraMessageBox.Show("请先选择Excel文件", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            try
            {
                PreviewImportData();
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show($"预览数据失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 导入按钮点击事件
        /// </summary>
        private void BtnImport_Click(object sender, EventArgs e)
        {
            if (_previewNodes == null || _previewNodes.Count == 0)
            {
                XtraMessageBox.Show("没有可导入的数据，请先预览数据", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            var result = XtraMessageBox.Show($"确定要导入 {_previewNodes.Count} 条数据吗？", "确认导入",
                MessageBoxButtons.YesNo, MessageBoxIcon.Question);

            if (result == DialogResult.Yes)
            {
                try
                {
                    ImportData();
                }
                catch (Exception ex)
                {
                    XtraMessageBox.Show($"导入数据失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        /// <summary>
        /// 清空按钮点击事件
        /// </summary>
        private void BtnClear_Click(object sender, EventArgs e)
        {
            ClearData();
        }

        /// <summary>
        /// 关闭按钮点击事件
        /// </summary>
        private void BtnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// 生成导入模板
        /// </summary>
        private void GenerateTemplate_Click(object sender, EventArgs e)
        {
            try
            {
                SaveFileDialog saveDialog = new SaveFileDialog
                {
                    Filter = "Excel文件|*.xlsx",
                    Title = "保存Excel模板",
                    FileName = "OPC_UA_节点配置模板.xlsx"
                };

                if (saveDialog.ShowDialog() == DialogResult.OK)
                {
                    ExcelTemplate.CreateImportTemplate(saveDialog.FileName);
                    MessageBox.Show("Excel模板生成成功！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"生成模板失败：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 导出当前数据
        /// </summary>
        private void ExportData_Click(object sender, EventArgs e)
        {
            try
            {
                var allNodes = _configService.GetAllNodes();
                if (allNodes == null || allNodes.Count == 0)
                {
                    MessageBox.Show("没有数据可以导出", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                SaveFileDialog saveDialog = new SaveFileDialog
                {
                    Filter = "Excel文件|*.xlsx",
                    Title = "导出Excel文件",
                    FileName = $"OPC_UA_节点配置_{DateTime.Now:yyyyMMdd_HHmmss}.xlsx"
                };

                if (saveDialog.ShowDialog() == DialogResult.OK)
                {
                    ExcelTemplate.ExportToExcel(saveDialog.FileName, allNodes);
                    MessageBox.Show($"数据导出成功！\n共导出 {allNodes.Count} 条记录", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"导出数据失败：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 网格行号绘制事件
        /// </summary>
        private void GridViewPreview_CustomDrawRowIndicator(object sender, DevExpress.XtraGrid.Views.Grid.RowIndicatorCustomDrawEventArgs e)
        {
            if (e.Info.IsRowIndicator && e.RowHandle >= 0)
            {
                e.Info.DisplayText = (e.RowHandle + 1).ToString();
            }
        }

        #endregion

        #region 核心方法

        /// <summary>
        /// 使用NPOI读取Excel文件
        /// </summary>
        /// <param name="filePath">文件路径</param>
        private void LoadExcelData(string filePath)
        {
            _importDataTable.Clear();
            _importDataTable.Columns.Clear();

            using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                IWorkbook workbook;
                string extension = Path.GetExtension(filePath).ToLower();

                // 根据文件扩展名创建相应的工作簿
                if (extension == ".xlsx")
                {
                    workbook = new XSSFWorkbook(file);
                }
                else if (extension == ".xls")
                {
                    workbook = new HSSFWorkbook(file);
                }
                else
                {
                    throw new ArgumentException("不支持的文件格式");
                }

                // 获取第一个工作表
                ISheet sheet = workbook.GetSheetAt(0);
                if (sheet == null)
                {
                    throw new Exception("Excel文件中没有找到工作表");
                }

                // 读取表头
                IRow headerRow = sheet.GetRow(0);
                if (headerRow == null)
                {
                    throw new Exception("Excel文件中没有找到表头行");
                }

                // 创建列
                for (int i = 0; i < headerRow.LastCellNum; i++)
                {
                    ICell cell = headerRow.GetCell(i);
                    string columnName = cell?.ToString()?.Trim() ?? $"Column{i + 1}";
                    _importDataTable.Columns.Add(columnName);
                }

                // 读取数据行
                for (int i = 1; i <= sheet.LastRowNum; i++)
                {
                    IRow row = sheet.GetRow(i);
                    if (row == null) continue;

                    DataRow dataRow = _importDataTable.NewRow();
                    bool hasData = false;

                    for (int j = 0; j < _importDataTable.Columns.Count && j < row.LastCellNum; j++)
                    {
                        ICell cell = row.GetCell(j);
                        string cellValue = GetCellValue(cell);
                        dataRow[j] = cellValue;
                        if (!string.IsNullOrWhiteSpace(cellValue))
                        {
                            hasData = true;
                        }
                    }

                    // 只添加有数据的行
                    if (hasData)
                    {
                        _importDataTable.Rows.Add(dataRow);
                    }
                }
            }

            // 绑定到网格
            gridControlRaw.DataSource = _importDataTable;
            _isDataLoaded = true;
            UpdateUIState();

            // 显示统计信息
            lblStatus.Text = $"已读取 {_importDataTable.Rows.Count} 行数据，{_importDataTable.Columns.Count} 列";
        }

        /// <summary>
        /// 获取单元格值
        /// </summary>
        /// <param name="cell">单元格</param>
        /// <returns>单元格值</returns>
        private string GetCellValue(ICell cell)
        {
            if (cell == null) return string.Empty;

            switch (cell.CellType)
            {
                case CellType.String:
                    return cell.StringCellValue?.Trim() ?? string.Empty;
                case CellType.Numeric:
                    if (DateUtil.IsCellDateFormatted(cell))
                    {
                        return cell.DateCellValue.Value.ToString("yyyy-MM-dd HH:mm:ss");
                    }
                    return cell.NumericCellValue.ToString();
                case CellType.Boolean:
                    return cell.BooleanCellValue.ToString();
                case CellType.Formula:
                    try
                    {
                        return cell.NumericCellValue.ToString();
                    }
                    catch
                    {
                        return cell.StringCellValue?.Trim() ?? string.Empty;
                    }
                default:
                    return string.Empty;
            }
        }

        /// <summary>
        /// 预览导入数据
        /// </summary>
        private void PreviewImportData()
        {
            _previewNodes.Clear();
            List<string> errorMessages = new List<string>();

            foreach (DataRow row in _importDataTable.Rows)
            {
                try
                {
                    var node = MapRowToEntity(row);
                    if (node != null)
                    {
                        // 检查是否已存在
                        var existingNode = _configService.GetNodeConfigByNodeId(node.NodeId);
                        
                        // 初始化节点属性字典
                        if (!_nodeProperties.ContainsKey(node))
                        {
                            _nodeProperties[node] = new Dictionary<string, object>();
                        }
                        
                        if (existingNode != null)
                        {
                            node.Id = existingNode.Id;
                            _nodeProperties[node]["ImportAction"] = "更新";
                        }
                        else
                        {
                            _nodeProperties[node]["ImportAction"] = "新增";
                        }

                        _previewNodes.Add(node);
                    }
                }
                catch (Exception ex)
                {
                    errorMessages.Add($"第{_importDataTable.Rows.IndexOf(row) + 2}行: {ex.Message}");
                }
            }

            // 绑定预览数据
            gridControlPreview.DataSource = _previewNodes;

            // 显示统计信息
            int newCount = _previewNodes.Count(n => _nodeProperties.ContainsKey(n) && 
                _nodeProperties[n].ContainsKey("ImportAction") && 
                _nodeProperties[n]["ImportAction"]?.ToString() == "新增");
            int updateCount = _previewNodes.Count(n => _nodeProperties.ContainsKey(n) && 
                _nodeProperties[n].ContainsKey("ImportAction") && 
                _nodeProperties[n]["ImportAction"]?.ToString() == "更新");
            
            string statusText = $"预览完成: 新增 {newCount} 条，更新 {updateCount} 条";
            if (errorMessages.Count > 0)
            {
                statusText += $"，错误 {errorMessages.Count} 条";
            }
            lblStatus.Text = statusText;

            // 显示错误信息
            if (errorMessages.Count > 0)
            {
                string errorText = "数据验证错误:\n" + string.Join("\n", errorMessages.Take(10));
                if (errorMessages.Count > 10)
                {
                    errorText += $"\n... 还有 {errorMessages.Count - 10} 个错误";
                }
                XtraMessageBox.Show(errorText, "数据验证", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }

            UpdateUIState();
        }

        /// <summary>
        /// 执行数据导入
        /// </summary>
        private void ImportData()
        {
            int insertCount = 0;
            int updateCount = 0;
            int errorCount = 0;
            List<string> errorMessages = new List<string>();

            foreach (var node in _previewNodes)
            {
                try
                {
                    string action = "插入"; // 默认为插入
                    if (_nodeProperties.ContainsKey(node) && _nodeProperties[node].ContainsKey("ImportAction"))
                    {
                        action = _nodeProperties[node]["ImportAction"]?.ToString() ?? "插入";
                    }
                    
                    if (action == "更新")
                    {
                        _configService.UpdateNode(node);
                        updateCount++;
                    }
                    else
                    {
                        _configService.AddNode(node);
                        insertCount++;
                    }
                }
                catch (Exception ex)
                {
                    errorCount++;
                    errorMessages.Add($"节点 {node.NodeId}: {ex.Message}");
                }
            }

            // 显示导入结果
            string message = $"导入完成！\n新增: {insertCount} 条\n更新: {updateCount} 条";
            if (errorCount > 0)
            {
                message += $"\n错误: {errorCount} 条";
                if (errorMessages.Count > 0)
                {
                    message += "\n\n错误详情:\n" + string.Join("\n", errorMessages.Take(5));
                    if (errorMessages.Count > 5)
                    {
                        message += $"\n... 还有 {errorMessages.Count - 5} 个错误";
                    }
                }
            }

            XtraMessageBox.Show(message, "导入结果", MessageBoxButtons.OK, MessageBoxIcon.Information);
            lblStatus.Text = $"导入完成: 新增 {insertCount} 条，更新 {updateCount} 条，错误 {errorCount} 条";
            
            // 设置对话框结果为OK，表示导入成功
            this.DialogResult = DialogResult.OK;
        }

        /// <summary>
        /// 将DataRow映射到OpcUaNodeConfigEntity
        /// </summary>
        /// <param name="row">数据行</param>
        /// <returns>节点配置实体</returns>
        private OpcUaNodeConfigEntity MapRowToEntity(DataRow row)
        {
            var node = new OpcUaNodeConfigEntity();

            // 映射Excel列到实体属性
            foreach (DataColumn column in row.Table.Columns)
            {
                string columnName = column.ColumnName.Trim();
                object value = row[column];

                if (value == null || value == DBNull.Value || string.IsNullOrWhiteSpace(value.ToString()))
                    continue;

                switch (columnName.ToLower())
                {
                    case "nodeid":
                    case "节点id":
                        node.NodeId = value.ToString().Trim();
                        break;
                    case "name":
                    case "名称":
                    case "节点名称":
                        node.Name = value.ToString().Trim();
                        break;
                    case "description":
                    case "描述":
                        node.Description = value.ToString().Trim();
                        break;
                    case "datatype":
                    case "数据类型":
                        node.DataType = value.ToString().Trim();
                        break;
                    case "accesslevel":
                    case "访问级别":
                        node.AccessLevel = value.ToString().Trim();
                        break;
                    case "scanrate":
                    case "扫描频率":
                        if (int.TryParse(value.ToString(), out int scanRate))
                            node.ScanRate = scanRate;
                        break;
                    case "propertyname":
                    case "属性名称":
                        node.PropertyName = value.ToString().Trim();
                        break;
                    case "objectname":
                    case "对象名称":
                        node.ObjectName = value.ToString().Trim();
                        break;
                    case "group":
                    case "分组":
                        node.Group = value.ToString().Trim();
                        break;
                    case "sort":
                    case "排序":
                        if (int.TryParse(value.ToString(), out int sort))
                            node.Sort = sort;
                        break;
                    case "remark":
                    case "备注":
                        node.Remark = value.ToString().Trim();
                        break;
                    case "issubscribed":
                    case "是否订阅":
                        if (bool.TryParse(value.ToString(), out bool isSubscribed))
                            node.IsSubscribed = isSubscribed;
                        else
                            node.IsSubscribed = value.ToString().Trim().ToLower() == "是" || value.ToString().Trim() == "1";
                        break;
                    case "isenabled":
                    case "是否启用":
                        if (bool.TryParse(value.ToString(), out bool isEnabled))
                            node.IsEnabled = isEnabled;
                        else
                            node.IsEnabled = value.ToString().Trim().ToLower() == "是" || value.ToString().Trim() == "1";
                        break;
                    case "writefunction":
                    case "写入功能":
                        if (int.TryParse(value.ToString(), out int writeFunction))
                            node.WriteFunction = writeFunction;
                        break;
                }
            }

            // 验证必填字段
            if (string.IsNullOrWhiteSpace(node.NodeId))
            {
                throw new ArgumentException("NodeId不能为空");
            }

            if (string.IsNullOrWhiteSpace(node.Name))
            {
                node.Name = node.NodeId; // 如果名称为空，使用NodeId作为名称
            }

            // 设置默认值
            if (string.IsNullOrWhiteSpace(node.DataType))
                node.DataType = "String";
            if (string.IsNullOrWhiteSpace(node.AccessLevel))
                node.AccessLevel = "Read";
            if (node.ScanRate <= 0)
                node.ScanRate = 1000;

            return node;
        }

        /// <summary>
        /// 清空数据
        /// </summary>
        private void ClearData()
        {
            txtFilePath.Text = string.Empty;
            _importDataTable.Clear();
            _importDataTable.Columns.Clear();
            _previewNodes.Clear();
            _nodeProperties.Clear();
            gridControlRaw.DataSource = null;
            gridControlPreview.DataSource = null;
            _isDataLoaded = false;
            lblStatus.Text = "就绪";
            UpdateUIState();
        }

        /// <summary>
        /// 更新UI状态
        /// </summary>
        private void UpdateUIState()
        {
            btnPreview.Enabled = _isDataLoaded;
            btnImport.Enabled = _previewNodes != null && _previewNodes.Count > 0;
            btnClear.Enabled = _isDataLoaded || (_previewNodes != null && _previewNodes.Count > 0);
        }

        #endregion

        #region 窗体事件

        /// <summary>
        /// 窗体关闭事件
        /// </summary>
        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            try
            {
                //_configService?.Dispose();
                _repository?.Dispose();
            }
            catch
            {
                // 忽略释放资源时的异常
            }
            base.OnFormClosing(e);
        }

        #endregion

        private void btnImport_Click_1(object sender, EventArgs e)
        {

        }
    }

    /// <summary>
    /// OpcUaNodeConfigEntity扩展方法
    /// </summary>
    public static class OpcUaNodeConfigEntityExtensions
    {
        private static readonly Dictionary<object, Dictionary<string, object>> _properties = new Dictionary<object, Dictionary<string, object>>();

        /// <summary>
        /// 设置属性
        /// </summary>
        public static void SetProperty(this OpcUaNodeConfigEntity entity, string key, object value)
        {
            if (!_properties.ContainsKey(entity))
            {
                _properties[entity] = new Dictionary<string, object>();
            }
            _properties[entity][key] = value;
        }

        /// <summary>
        /// 获取属性
        /// </summary>
        public static object GetProperty(this OpcUaNodeConfigEntity entity, string key)
        {
            if (_properties.ContainsKey(entity) && _properties[entity].ContainsKey(key))
            {
                return _properties[entity][key];
            }
            return null;
        }
    }
}